package com.gid.rcflightlogger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;


public abstract class InventoryBrowseBaseActivity extends BaseActivity {

	protected List<Object> mData;
	
	public static final int REQUEST_CODE_ADD = 1;
	public static final int REQUEST_CODE_EDIT = 2;
	
	protected TableLayout mTableLayout;
	protected TableRow mHeaderRow;
	protected Button mAdd;
	
	//sort data
	protected int COLUMN_COUNT = 0;
	protected List<TextView> mHeaders;
	protected int sortColumn = -1; //index into column used for sorting, -1 = no sort
	protected boolean sortUp = false;
	protected static final String PREF_SORT_COLUMN_KEY = "SortColumn";
	protected static final String PREF_SORT_DIR_KEY = "SortUp";
	protected String PREF_PREFIX = "InventoryBrowseBase";
	
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_inventorybrowse_common);
        mTableLayout = (TableLayout) findViewById(R.id.inventorybrowse_table);
        mAdd = (Button) findViewById(R.id.inventorybrowse_btn_add);
        mAdd.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				spawnItemEditor(REQUEST_CODE_ADD, 0);
			}
		});
        
        mData = new ArrayList<Object>();
        
        //setup header text fields
        mHeaders = new ArrayList<TextView>();
        mHeaderRow = renderHeaders();
        mTableLayout.addView(mHeaderRow, 0);
        
        COLUMN_COUNT = mHeaderRow.getChildCount();
        for (int i = 0; i < COLUMN_COUNT; i++)
        {
        	TextView tv = (TextView)mHeaderRow.getChildAt(i);
        	tv.setOnClickListener(mHeaderOnClickListener);
        	mHeaders.add(tv);
        }
                
        //retrieving sort preferences: column, direction
        loadPrefs();
	}
	
    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        loadData();
        sortData();
        redrawTable();
    }
	
	private void redrawTable()
	{
		//update appearance of headers
		for (TextView v : mHeaders)
			v.setTextColor(Colors.TABLE_HEADER_NORMAL);
		
		if (sortColumn >= 0 && sortColumn < COLUMN_COUNT)
			mHeaders.get(sortColumn).setTextColor(sortUp ? Colors.TABLE_HEADER_UP : Colors.TABLE_HEADER_DOWN);
		
		//repopulate table
		mTableLayout.removeViews(2, mTableLayout.getChildCount() - 2); //keep the header and border
		
		for (Object od : mData) 
		{
			TableRow tr = renderRow(od);
			tr.setPadding(0, 2, 0, 0);	
			tr.setClickable(true); 
			tr.setOnTouchListener(mRowOnTouchListener);
			tr.setOnLongClickListener(mRowOnLongClickListener);
			tr.setFocusable(true);
			tr.setOnFocusChangeListener(mRowOnFocusChangeListener);
			
			mTableLayout.addView(tr);
			
			//table's horizontal line
			View ruler = new View(getApplicationContext());
			ruler.setBackgroundColor(0x88909090);
			mTableLayout.addView(ruler,new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 1));
		}
	}
	
	//changes highlighted state of a given table row, by adding or removing bg color
	private void highlightTableRow(TableRow r, boolean highlighted)
	{
		if (highlighted)
		{
			r.setBackgroundColor(Colors.TABLE_ROW_BGHIGHLIGHT); //android default list selector bg color
			r.invalidate();
		}
		else
		{
			r.setBackgroundResource(0);
			r.invalidate();
		}
	}
	
	private void loadPrefs()
	{
        int col = mPrefs.getInt(PREF_PREFIX + PREF_SORT_COLUMN_KEY, -1);
        if (col >= 0 && col < COLUMN_COUNT)
        {
        	sortColumn = col;
        	sortUp = mPrefs.getBoolean(PREF_PREFIX + PREF_SORT_DIR_KEY, false);
        }
	};
	
	private void savePrefs()
	{
		mPrefsEditor.putInt(PREF_PREFIX + PREF_SORT_COLUMN_KEY, sortColumn);
		mPrefsEditor.putBoolean(PREF_PREFIX + PREF_SORT_DIR_KEY, sortUp);
		mPrefsEditor.commit();
	};
	
	// ====================================================
	// Various utilities (listeners/comparators)
	// ====================================================
	private TableRow.OnTouchListener mRowOnTouchListener = new TableRow.OnTouchListener()
    {
		@Override
		public boolean onTouch(View v, MotionEvent event)
		{
			final int action = event.getAction();
			switch (action & MotionEvent.ACTION_MASK)
			{
				case MotionEvent.ACTION_UP:
				case MotionEvent.ACTION_CANCEL:
				case MotionEvent.ACTION_OUTSIDE:
				//case MotionEvent.ACTION_MOVE:
					highlightTableRow((TableRow) v, false);
					break;
				default:
					highlightTableRow((TableRow) v, true);
			}
			return false;
		}
    };
    
    private TableRow.OnLongClickListener mRowOnLongClickListener = new TableRow.OnLongClickListener()
    {
    	@Override
		public boolean onLongClick(View v) {
    		spawnItemEditor(REQUEST_CODE_EDIT, v.getId());
			return true;
		}
    };
    
    private TableRow.OnFocusChangeListener mRowOnFocusChangeListener = new View.OnFocusChangeListener() {
		@Override
		public void onFocusChange(View v, boolean hasFocus) {
			highlightTableRow((TableRow) v, hasFocus);			
		}
    };
    
    private TextView.OnClickListener mHeaderOnClickListener = new View.OnClickListener() {
		
		@Override
		public void onClick(View v) {
			int colid = -1;
			for (int i = 0; i < COLUMN_COUNT; i++)
			{
				if (mHeaders.get(i) == v)
				{
					colid = i;
				}
			}
			if (colid == -1)
				return; //this should not happen
			
			//update sort configuration
			if (colid != sortColumn)
			{
				//this is a new sort column
				sortColumn = colid;
				sortUp = false;
			}
			else
			{
				//same column, change direction or turn off
				if (sortUp == false)
				{
					sortUp = true;
				}
				else
				{
					sortColumn = -1;
				}	
			}
			
			sortData();
			redrawTable();
			savePrefs();
		}
	};
	
	protected void sortData() {
		Collections.sort(mData, mDataComparator);
	}
	
	private class DataComparator implements Comparator<Object> {
		@Override
		public int compare(Object lhs, Object rhs) {
			return doCompare(lhs, rhs);
		}
	};
	private DataComparator mDataComparator = new DataComparator();
	
	// ====================================================
	// Various abstract methods
	// ====================================================

	//initializes the layout of headers and insert header text views in mHeaders list
	protected abstract TableRow renderHeaders();
	
	protected abstract void spawnItemEditor (int request_code, int id);
	
	//load data from database in mData
	protected abstract void loadData();
	
	//sort data in mData based on current sort settings
	protected abstract int doCompare(Object lhs, Object rhs);
	
	//render inventory entry row
	//TableRow object's Id must be set to data object's database id
	protected abstract TableRow renderRow(Object od);
}
